#pragma once

#include <vector>
#include <list>

#include "ofMain.h"

#include "Block.h"

#include "ItemParticle.h"

using namespace std;

/** Manages the tile-based world, and all particles and entities
    contained by the world.
**/
class Environment
{
public:
    const int sX, /**< Size of the world in the X-Direction (in blocks) **/
              sY; /**< Size of the world in the Y-Direction (in blocks) **/

    /** Constructor. **/
    Environment(void);
    /** Destructor **/
    ~Environment(void);

    /** Draws all the blocks in the world.
        \param drawScale drawScale member of the main BlockCraft app
        \param viewOffset viewOffset member of the main BlockCraft app
    **/
    void draw(float drawScale, ofPoint viewOffset);

    /** Manages all math and time-based events for blocks. **/
    void update();

    /** (needs documentation)
    **/
    void placeBlock(int ID);
    /** (needs documentation)
    **/
    void placeBlockAtCoord(int x, int y, Block *newlyAllocatedBlock = NULL);

    /** (needs documentation)
    **/
    void addItemParticle(ofPoint loc, ofPoint vel, int ID);

    /** Obtain the block containing the x and y coordinate given.
        \param x X-Coordinate to locate a block by
        \param y Y-Coordinate to locate a block by
        \return Reference to the block that has been found
    **/
    Block& blockByCoord(int x, int y);

    /** Obtain pointer to a block that is active.
        \return Block pointer to the targeted block by the player
    **/
    Block* activeBlock();

    vector<vector<Block*> >& wgrid();   /**< Retrieves the world grid as a vector of vectors of blocks. **/

    list<Particle*> particles;          /**< All Particles contained in the world **/
    list<ItemParticle*> itemParticles;  /**< All ItemParticles contained in the world **/

private:
    vector<vector<Block*> > world;  /**< Contains all blocks in the world. **/

    /** Determines if a space is not currently occupied by a player.
        \param x X-Coordinate of point to check
        \param y Y-Coordinate of point to check
        \return true if point is not contained within player's bounding box, false otherwise
    **/
    bool spaceNotOccupiedByPlayer(int x, int y);

    /** Determines if a point is within current draw area.
        \param x X-Coordinate to check
        \param y Y-Coordinate to check
        \param drawScale drawScale member of the main BlockCraft app
        \param viewOffset viewOffset member of the main BlockCraft app
        \return true if object is within current draw area
    **/
    bool objIsInView(float x, float y, float drawScale, ofPoint viewOffset);
};
